﻿function TreeGrid_PopulateNode(data, index, my, expandIndicator, nodeImage, lineType, path, databound, parentIsLast) {
    // 保存上下文
    var context = new Object();
    context.data = data;
    context.index = index;
    context.my = my;
    context.expandIndicator = expandIndicator;
    context.nodeImage = nodeImage;
    context.lineType = lineType;
    context.path = path;
    context.databound = databound;
    context.parentIsLast = parentIsLast;

    // 准备CallBack参数
    var param = index + "|" + data.lastIndex + "|" + data.lastId + "|" + databound + "|" + parentIsLast + "|" + path;
    TreeGrid_PopulateNodeDoCallBack(context, param);
}

function TreeGrid_ProcessNodeData(result, context) {    
    if (result.length > 0) {
        // lastIndex
        var ci =  result.indexOf("|", 0);
        context.data.lastIndex = result.substring(0, ci); 
        var si = context.data.lastIndex.length + 1;
        // lastId
        ci = result.indexOf("|", ci + 1);
        context.data.lastId = result.substring(si, ci);
        si = si + context.data.lastId.length + 1;
        // expandState
        ci = result.indexOf("|", ci + 1);
        var newExpandState = result.substring(si, ci);
        si = si + newExpandState.length + 1;
        context.data.expandState.value += newExpandState;
        // nodeRealtion
        ci = result.indexOf("|", ci + 1);
        var childRelation = result.substring(si, ci);
        si = si + childRelation.length + 1;
        var td = WebForm_GetParentByTagName(context.my, "td");
        if (!td) {return;}
        var pNodeRelation = TreeGrid_FindNodeRelationByNodeId(context.data.relation.n, td.id);          // eval(context.data.relation) apply to string
        if (!pNodeRelation) {return;}
        var tr = WebForm_GetParentByTagName(td, "TR");
        if (!tr) {return;}
        TreeGrid_NodesRelationAddChildren(childRelation, pNodeRelation);
        
        // html
        var chunk = result.substr(ci + 1);


        var hasChild = false;
        var newDiv = document.createElement("div");
        newDiv.innerHTML = chunk;
        var newNodes = newDiv.firstChild.rows;
        if (newNodes.length > 0) {
            hasChild = true;
        }
        var rowIndex;
        var nextTr = tr.nextSibling;
        if (__nonMSDOMBrowser) {
            var table = WebForm_GetParentByTagName(tr, "TABLE");
            newChildren = null;
            
            for (var rowIndex=0; rowIndex < newNodes.length; rowIndex++) {
                table.insertBefore(newNodes[rowIndex], nextTr);
            }
        }
        else {
            //tr.insertAdjacentHTML("afterEnd", chunk); tr not support
            //for (var rowIndex=0; rowIndex < newNodes.length; rowIndex++) {
            //    nextTr.insertAdjacentElement("beforeBegin", newNodes[rowIndex]);
            //}
            while (newNodes.length > 0) {
                nextTr.insertAdjacentElement("beforeBegin", newNodes[0]);
            }
        }
        if (hasChild) {
            TreeGrid_ToggleNode(context.data, context.index, context.my, context.expandIndicator, context.lineType, context.data.relation);
            context.my.href = document.getElementById ?
                "javascript:TreeGrid_ToggleNode(" + context.data.name + "," + context.index + ",document.getElementById('" + context.my.id + "')," + "document.getElementById('" + context.expandIndicator.id + "'),'" + context.lineType + "'," + context.data.relationName + ".n)" :
                "javascript:TreeGrid_ToggleNode(" + context.data.name + "," + context.index + "," + context.my.id + context.expandIndicator.id + ",'" + context.lineType + "'," + context.data.relationName + ".n)";
            //if ((typeof(context.selectNode) != "undefined") && (context.my != null) && context.my.href &&
            //    (context.my.href.indexOf("javascript:TreeGrid_PopulateNode", 0) == 0)) {
            //    context.my.href = context.my.href;
            //}
            if ((typeof(context.nodeImage) != "undefined") && (context.nodeImage != null) && context.nodeImage.href &&
                (context.nodeImage.href.indexOf("javascript:TreeGrid_PopulateNode", 0) == 0)) {
                context.nodeImage.href = context.my.href;
            }
        }
        context.data.populateLog.value += context.index + ",";
    }
    else {
        var img = context.expandIndicator;
        if ((typeof(img) != "undefined") && (img != null)) {
            var lineType = context.lineType;
            if (lineType == "l") {
                img.src = context.data.images[13];
            }
            else if (lineType == "t") {
                img.src = context.data.images[10];
            }
            else if (lineType == "-") {
                img.src = context.data.images[16];
            }
            else {
                img.src = context.data.images[3];
            }
        }
    }
}

function TreeGrid_SelectNode(data, node, nodeId) {
    if ((typeof(data.selectedClass) != "undefined") && (data.selectedClass != null)) {
        var id = data.selectedNodeID.value;
        if (id.length > 0) {
            var selectedNode = document.getElementById(id);
            if ((typeof(selectedNode) != "undefined") && (selectedNode != null)) {
                WebForm_RemoveClassName(selectedNode, data.selectedHyperLinkClass);
                if (selectedNode.tagName.toUpperCase() != "TD") {
                    selectedNode = WebForm_GetParentByTagName(selectedNode, "TD");
                }
                WebForm_RemoveClassName(selectedNode, data.selectedClass);
            }
        }
        WebForm_AppendToClassName(node, data.selectedHyperLinkClass);
        node = WebForm_GetParentByTagName(node, "TD");
        WebForm_AppendToClassName(node, data.selectedClass)
    }
    data.selectedNodeID.value = nodeId;
}



/******************************************************************************/
// 向NodesRelation定义添加子节点
// nodesStr -- 按照JSON格式定义的子孙节点关系
// parent   -- NodesRelation中定义的节点，作为父节点
function TreeGrid_NodesRelationAddChildren(nodesStr, parent) {
    var nodes = eval('(' + nodesStr + ')');
    if (nodes) {
        parent.c = nodes.n;
    }
    else {
        return;
    }
}

// 切换节点状态(并设置图像,保存状态)
// data         -- clientDataObject
// index        -- 节点的Index
// toggleBy     -- 引发Toggle事件的控件
// indicator    -- 节点的展开指示符控件
// lineType     -- 当前的线性
// relation     -- NodesRelation
function TreeGrid_ToggleNode(data, index, toggleBy, indicator, lineType, relation)
{
    if (!toggleBy) {return;}
    
    var nodeTd = WebForm_GetParentByTagName(toggleBy, "TD");                // 获得节点所在TD
    if (!nodeTd) {return;}
    var nodeTr = WebForm_GetParentByTagName(nodeTd, "TR");                  // 获得节点所在TR
    if (!nodeTr) {return;}
    var nodeR = TreeGrid_FindNodeRelationByNodeId(relation, nodeTd.id);     // 根据td.id查找在relation对应的关系
    if (!nodeR) {return;}
    
    TreeGrid_ToggleNodeExpandState(nodeTd, nodeTr, nodeR);
    
    var img = indicator.childNodes[0];
    var newExpandState;
    try {
        if (nodeR.e == "e") {
            newExpandState = "e";
            if ((typeof(img) != "undefined") && (img != null)) {
                if (lineType == "l") {
                    img.src = data.images[15];
                }
                else if (lineType == "t") {
                    img.src = data.images[12];
                }
                else if (lineType == "-") {
                    img.src = data.images[18];
                }
                else {
                    img.src = data.images[5];
                }
                img.alt = data.collapseToolTip.replace(/\{0\}/, "");
            }
        }
        else {
            newExpandState = "c";
            if ((typeof(img) != "undefined") && (img != null)) {
                if (lineType == "l") {
                    img.src = data.images[14];
                }
                else if (lineType == "t") {
                    img.src = data.images[11];
                }
                else if (lineType == "-") {
                    img.src = data.images[17];
                }
                else {
                    img.src = data.images[4];
                }
                img.alt = data.expandToolTip.replace(/\{0\}/, "");
            }
        }
    }
    catch(e) {}
    data.expandState.value =  data.expandState.value.substring(0, index) + newExpandState + data.expandState.value.slice(index + 1);
}

// 切换节点状态(只处理节点的展开/关闭状态)
// toggleBy -- 引发Toggle事件的控件
function TreeGrid_ToggleNodeExpandState(toggleTd, toggleTr, nodeR)
{    
    var td, tr;
    td = toggleTd;
    tr = toggleTr;
    
    var nodeC = TreeGrid_GetNodeChildrenRelation(nodeR, true);  // 获得节点所有的子孙节点（不包括自己）（深度遍历）
    if (!nodeC) {return;}

    var expand = (nodeR.e == "e") ? false : true;               // 根据节点的状态，判断进行展开还是关闭
    nodeR.e = (nodeR.e == "e") ? "c" : "e";                     // 切换节点的状态
    tr = tr.nextSibling;                                        // 
    var nodeChildrenCount = 0;                                  // 直接子节点数
    
    if (tr && (nodeC.length > 0)) {
        var directChildExpanded = false;
        for (var cIndex = 0; cIndex < nodeC.length; cIndex++) { // 循环--巧妙的循环(各行tr是深度遍历的结果,nodeC也是深度遍历的结果)
            if (!expand) {                                      // 切换为关闭状态 -- 设置节点的直接子节点pe = "c".
                tr.style.display = "none";

                // 只处理直接子节点
                if (nodeChildrenCount == 0) {                   // 第一次时为true，以后每次获得的都是直接子节点的子孙节点的个数。
                    nodeChildrenCount = TreeGrid_GetNodeChildrenCount(nodeC[cIndex]);        // 获得所有子孙节点的个数（不包括自己）
                    //alert(nodeChildrenCount);
                    nodeC[cIndex].pe = "c";
                    //alert("ok" + nodeC[cIndex].pe + nodeC[cIndex].i);
                }
                else {
                    nodeChildrenCount--;                        // -- 处理下个节点。连续跳过，直到遇到下一个直接子节点
                }
            }
            else {                                              // 切换为展开状态 -- 一个子孙节点是否展开，取决于其父节点是否展开(更准确应为祖先节点)(是否有规则保证仅检验父呢?)
                if (nodeChildrenCount == 0) {                   // 直接子节点一定展开
                    nodeChildrenCount = TreeGrid_GetNodeChildrenCount(nodeC[cIndex]);    //alert(nodeChildrenCount);
                    nodeC[cIndex].pe = "e";
                    tr.style.display = "block";
                    
                    // 如果直接子节点是关闭的，那么这个直接子节点的所有子孙，无论父节点是否展开，都不应展开。
                    directChildExpanded = (nodeC[cIndex].e == "e") ? true : false;   // 直接子节点的状态
                }
                else {
                    nodeChildrenCount--;
                    if (directChildExpanded && nodeC[cIndex].pe == "e") {    // 直接子节点是展开的 且 父节点是展开的
                        tr.style.display = "block";
                    }
                }
            }
            
            if (cIndex < nodeC.length-1) {
                tr = tr.nextSibling;                            // 下一行
            }
        }
        //var checkbox = tr.getElementsByTagName("INPUT");
    }
}

// 根据指定的id，按照i属性在指定的NodeRelation定义中查找对应的节点关系
// realtion -- 要在其中进行查找的NodeRelation对象
// nodeId   -- 要查找的节点定义的i属性值
function TreeGrid_FindNodeRelationByNodeId(relation, nodeId) {
    var nodeChildren = new Array();
    var nodeStack = new Array();
    var nodeTmp = relation;     // root
    var hasFind = false;
    
    // 深度遍历，堆栈
    while (nodeTmp || nodeStack.length > 0) {
        if (nodeTmp) { 
            if (!hasFind) {
                if (nodeTmp.i == nodeId) {
                    return nodeTmp;
                }
            }
            
            if (nodeTmp.c && nodeTmp.c.length > 0) {            // 子入栈
                for (var cIndex = nodeTmp.c.length-1; cIndex >= 0; cIndex--) {
                    nodeStack.push(nodeTmp.c[cIndex]);
                }
            }
            
            nodeTmp = null;                                     // 
        }
        else {
            nodeTmp = nodeStack.pop();                          // 出栈
        }
    }
    
    if (hasFind) {
        return nodeTmp;
    }
    else {
        return null;
    }
}



// 获得指定节点关系的所有子孙节点关系(深度遍历)
// nodeRelation     -- 根
// excludeParent    -- 是否包括根
function TreeGrid_GetNodeChildrenRelation(nodeRelation, excludeParent)
{
    var nodeChildren = new Array();
    var nodeStack = new Array();
    var nodeTmp = nodeRelation;         // root
    
    // 深度遍历，堆栈
    while (nodeTmp || nodeStack.length > 0) {
        if (nodeTmp) { 
            nodeChildren.push(nodeTmp);
            
            if (nodeTmp.c && nodeTmp.c.length > 0) {            // 子入栈
                for (var cIndex = nodeTmp.c.length-1; cIndex >= 0; cIndex--) {
                    nodeStack.push(nodeTmp.c[cIndex]);
                }
            }
            
            nodeTmp = null;
        }
        else {
            nodeTmp = nodeStack.pop();                          // 出栈
        }
    }
    
    if (excludeParent && excludeParent == true) {
        nodeChildren.shift();
    }
    
    return nodeChildren;
}

// 获得指定节点关系的所有子孙节点关系的个数(不含根)
// nodeRelation     -- 根
function TreeGrid_GetNodeChildrenCount(nodeRelation)
{
    if (!nodeRelation || !nodeRelation.c || nodeRelation.c.length == 0) {
        return 0;
    }
    
    var nodeStack = new Array();
    var nodeTmp = nodeRelation;                                 // root
    var nodeCount = 0;
    
    // 深度遍历，堆栈
    while (nodeTmp || nodeStack.length > 0) {
        if (nodeTmp) { 
            nodeCount++;
            
            if (nodeTmp.c && nodeTmp.c.length > 0) {            // 子入栈
                for (var cIndex = nodeTmp.c.length-1; cIndex >= 0; cIndex--) {
                    nodeStack.push(nodeTmp.c[cIndex]);
                }
            }
            
            nodeTmp = null;
        }
        else {
            nodeTmp = nodeStack.pop();                          // 出栈
        }
    }
    
    nodeCount--;
    return nodeCount;
}


/******************************************************************************/
/*
function TreeView_HoverNode(data, node) {
    node.hoverClass = data.hoverClass;
    WebForm_AppendToClassName(node, data.hoverClass);
    if (__nonMSDOMBrowser) {
        node = node.childNodes[node.childNodes.length - 1];
    }
    else {
        node = node.children[node.children.length - 1];
    }
    node.hoverHyperLinkClass = data.hoverHyperLinkClass;
    WebForm_AppendToClassName(node, data.hoverHyperLinkClass);
}
function TreeView_UnhoverNode(node) {
    WebForm_RemoveClassName(node, node.hoverClass);
    if (__nonMSDOMBrowser) {
        node = node.childNodes[node.childNodes.length - 1];
    }
    else {
        node = node.children[node.children.length - 1];
    }
    WebForm_RemoveClassName(node, node.hoverHyperLinkClass);
}
*/